在Swoole低版本中, 协程中使用exit强行退出脚本会导致内存错误导致不可预期的结果或coredump, 在Swoole服务中使用exit会使整个服务进程退出且内部的协程全部异常终止导致严重问题
Swoole长期以来一直禁止开发者使用exit, 但开发者可以使用抛出异常这种非常规的方式, 在顶层catch来实现和exit相同的退出逻辑
4.2.2版本及以上允许脚本(未创建http_server)在只有当前协程的情况下exit退出
Swoole**4.1.0
**版本及以上直接支持了在协程
, 服务事件循环
中使用PHP的exit
, 此时底层会自动抛出一个可捕获的Swoole\\ExitException
, 开发者可以在需要的位置捕获并实现与原生PHP一样的退出逻辑.
Swoole\\ExitException
继承于Exception
且新增了两个方法getStatus
和getFlags
:
namespace Swoole;
class ExitException extends \Exception
{
public function getStatus():mixed
public function getFlags():int
}
public function getStatus():mixed
获取exit($status)退出时的传入的status
参数, 支持任意的变量类型
public function getFlags():int
获取exit退出时所处的环境信息掩码, 目前有以下掩码
SWOOLE_EXIT_IN_COROUTINE //协程中退出
SWOOLE_EXIT_IN_SERVER //服务中退出
function route()
{
controller();
}
function controller()
{
your_code();
}
function your_code()
{
co::sleep(.001);
exit(1);
}
go(function () {
try {
route();
} catch (\Swoole\ExitException $e) {
assert($e->getStatus() === 1);
assert($e->getFlags() === SWOOLE_EXIT_IN_COROUTINE);
return;
}
});
<?php
$exit_status = 0;
go(function () {
try {
exit(123);
} catch (\Swoole\ExitException $e) {
global $exit_status;
$exit_status = $e->getStatus();
}
});
swoole_event_wait();
exit($exit_status);
swoole_async_set([
'enable_coroutine' => false
]);
swoole_timer_after(1000, function () {
exit;
});